﻿using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using WeBlog.Interfaces;

namespace WeBlog.Models
{
    public class User : IModel
    {
        public User()
        {
            DateCreated = DateTime.Now;
        }

        [Key]
        public int UserId { get; set; }

        [Required]
        [StringLength(50)]
        public string FirstName { get; set; }

        [Required]
        [StringLength(50)]
        public string LastName { get; set; }

        [Required]
        [StringLength(255)]        
        public string PasswordHash { get; set; }        

        [Required]
        [StringLength(255)]        
        public string Email { get; set; }

        public DateTime DateCreated { get; set; }
        public DateTime? LastLoginTime { get; set; }

        public Boolean Activated { get; set; }

        public int RoleFlag { get; set; }

        public virtual ICollection<Post> Posts { get; set; }

        public virtual ICollection<Page> Pages { get; set; }

        public string Password
        {            
            set { PasswordHash = Md5Encrypt(value); }
        }

        public string FullName
        {
            get { return String.Join(" ", new[] {FirstName, LastName}); }
        }

        public bool IsInRole(string name)
        {
            var role = RoleRepository.FindByName(name);
            return (role.RoleValue & RoleFlag) == role.RoleValue;
        }

        public string[] GetRoles()
        {
            return (from
                        Role role in RoleRepository.FindRoles()
                    where
                        IsInRole(role.Name)
                    select
                        role.Name).ToArray();
        }        

        private static string Md5Encrypt(string data)
        {            
            var encoding = new ASCIIEncoding();
            var bytes = encoding.GetBytes(data);
            var hashed = MD5.Create().ComputeHash(bytes);
            return Encoding.UTF8.GetString(hashed);
        }        

        internal static string GenerateRandomString()
        {
            var builder = new StringBuilder();
            var random = new Random();
            for (int i = 0; i < 6; i++)
            {
                char ch = Convert.ToChar(Convert.ToInt32(Math.Floor(26 * random.NextDouble() + 65)));
                builder.Append(ch);
            }
            return builder.ToString();
        } 

        public string ResetPassword()
        {
            var newPass = GenerateRandomString();
            Password = newPass;
            return newPass;
        }

        public bool Validate( string password )
        {
            var encoded = Md5Encrypt(password);
            return PasswordHash.Equals(encoded);
        }
    }
}
